﻿// -----------------------------------------------------------------------
// <copyright file="Shot.cs" company="Microsoft">
// TODO: Update copyright text.
// </copyright>
// -----------------------------------------------------------------------

namespace SpaceshipDuel
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using Microsoft.Xna.Framework.Graphics;
    using Microsoft.Xna.Framework;

    /// <summary>
    /// TODO: Update summary.
    /// </summary>
    public class Shot
    {
        #region Public fields

        public Vector2 position;    // Position
        public bool destroyMe;      // Flag zum Löschen des Schusses
        public Rectangle rectangle; // Rechteck der Textur

        #endregion Public fields

        #region Private fields

        Texture2D texture;          // Textur
        float speed;                // Geschwindigkeit
        float rotationAngle;        // Rotationswinkel des Raumschiffs = Rotation des Schusses für richtige Ausrichtung der Textur
        float maxTravelDistance;    // Maximale Strecke, die der Schuss zurücklegen kann, bevor er gelöscht wird
        int worldSize;              // Größe des Spielfeldes
        Vector2 direction;          // Richtungsvektor der Schussrichtung (normiert)
        Vector2 startPosition;      // Startpunkt

        #endregion Private fields

        #region Construction

        /// <summary>
        /// Konstruktor
        /// </summary>
        /// <param name="newTexture">Textur des Schusses</param>
        /// <param name="newPosition">Startposition des Schusses</param>
        /// <param name="newWorldSize">Größe des Spielfeldes</param>
        /// <param name="newSpeed">Geschossgeschwindigkeit</param>
        /// <param name="newRotation">aktueller Rotationswinkel des Raumschiffs = Orientierung der Schusstextur</param>
        /// <param name="newDirection">Richtungsvektor für Richtung des Schusses (normiert)</param>
        /// <param name="newMaxTravelDistance">Reichweite des Schusses</param>
        public Shot(Texture2D newTexture, Vector2 newPosition, int newWorldSize, float newSpeed, float newRotation, Vector2 newDirection, float newMaxTravelDistance)
        {
            texture = newTexture;
            position = newPosition;
            rectangle = new Rectangle((int)position.X, (int)position.Y, texture.Width, texture.Height);
            startPosition = position;
            speed = newSpeed;
            worldSize = newWorldSize;
            direction = newDirection;
            rotationAngle = newRotation;
            maxTravelDistance = newMaxTravelDistance;
            destroyMe = false;

            Update();
        }

        #endregion Construction

        #region Public methods

        /// <summary>
        /// Update-Methode für den Schuss
        /// </summary>
        public void Update()
        {
            position += direction * speed;
            CheckPosition();
            rectangle = new Rectangle((int)position.X, (int)position.Y, texture.Width, texture.Height);

            float distance = (startPosition - position).Length();

            if (distance >= maxTravelDistance)
                destroyMe = true;
        }

        /// <summary>
        /// Draw-Methode für den Schuss
        /// </summary>
        /// <param name="spriteBatch">Spritebacth</param>
        /// <param name="xOffset">Offset X</param>
        /// <param name="yOffset">Offset Y</param>
        public void Draw(SpriteBatch spriteBatch, float xOffset, float yOffset)
        {
            spriteBatch.Draw(texture, new Vector2(rectangle.X + xOffset, rectangle.Y + yOffset), null, Color.White, rotationAngle, new Vector2(texture.Width / 2, texture.Height / 2), 1.0f, SpriteEffects.None, 0f);
        }

        #endregion Public methods

        #region Private methods

        /// <summary>
        /// Korrektur der Position, wenn der Schuss über den Spielfeldrand hinausfliegt
        /// </summary>
        private void CheckPosition()
        {
            if (position.X < 0)
            {
                float distance = (startPosition - position).Length();
                position.X = worldSize + position.X;
                RecalculateMaxTravelDistance(distance);
            }
            else if (position.X >= worldSize)
            {
                float distance = (startPosition - position).Length();
                position.X = position.X - worldSize;
                RecalculateMaxTravelDistance(distance);
            }

            if (position.Y < 0)
            {
                float distance = (startPosition - position).Length();
                position.Y = worldSize + position.Y;
                RecalculateMaxTravelDistance(distance);
            }
            else if (position.Y >= worldSize)
            {
                float distance = (startPosition - position).Length();
                position.Y = position.Y - worldSize;
                RecalculateMaxTravelDistance(distance);
            }
        }

        /// <summary>
        /// Anpassung der MaxDistanz-Berechnung, wenn der Schuss über den Spielfeldrand hinausfliegt
        /// </summary>
        /// <param name="distance">bisher zurückgelegte Entfernung des Schusses</param>
        private void RecalculateMaxTravelDistance(float distance)
        {
            maxTravelDistance -= distance;
            startPosition = position;
        }

        #endregion Private methods

        
    }
}
